/*
 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang;
import java.lang.ref.*;

/**
 * This class extends <tt>ThreadLocal</tt> to provide inheritance of values
 * from parent thread to child thread: when a child thread is created, the
 * child receives initial values for all inheritable thread-local variables
 * for which the parent has values.  Normally the child's values will be
 * identical to the parent's; however, the child's value can be made an
 * arbitrary function of the parent's by overriding the <tt>childValue</tt>
 * method in this class.
 *
 * <p>Inheritable thread-local variables are used in preference to
 * ordinary thread-local variables when the per-thread-attribute being
 * maintained in the variable (e.g., User ID, Transaction ID) must be
 * automatically transmitted to any child threads that are created.
 *
 * @author  Josh Bloch and Doug Lea
 * @see     ThreadLocal
 * @since   1.2
 *
 * 功能：父子线程在传递 threadLocal 的时候会用到，在 Thread 类中有一个 inheritableThreadLocals 变量。
 *
 * Q1：父子线程的数据传递是在什么时候执行的？
 * A1：在 {@link Thread#init(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String, long, java.security.AccessControlContext, boolean)}，
 *    该方法在 new Thread() 的时候会被调用。也就是说，InheritableThreadLocal 传递 value 只发生在子线程初始化的时候。
 *
 * Q2：你看，又有了新的问题。我们通常在项目开发中是不会手动创建线程的，而是把我们的任务（Runnable/Callable）直接扔给线程池，
 *     让线程池进行调度，分配线程来执行任务。在线程池中，线程{@link java.util.concurrent.ThreadPoolExecutor.Worker#thread}
 *     是会被经常复用的，而对于 worker 来说是并不关心谁是父线程的。
 *     所以说，往线程池中提交任务的时候，除非是线程池刚好创建了一个新线程，才能顺利获取到父线程传递的数据，否则大多数情况下
 *     都只是复用线程池中已存在的线程，这种情况下，线程中的 value 早就不是当前线程想要传递的值了。
 * A2：解决方案呢，又是阿里巴巴，创造了一个叫【transmittable-thread-local】的东东，又叫 TTL。
 *     gitee 地址：https://gitee.com/mirrors/transmittable-thread-local
 */

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
    /**
     * Computes the child's initial value for this inheritable thread-local
     * variable as a function of the parent's value at the time the child
     * thread is created.  This method is called from within the parent
     * thread before the child is started.
     * <p>
     * This method merely returns its input argument, and should be overridden
     * if a different behavior is desired.
     *
     * @param parentValue the parent thread's value
     * @return the child thread's initial value
     */
    protected T childValue(T parentValue) {
        return parentValue;
    }

    /**
     * Get the map associated with a ThreadLocal.
     *
     * @param t the current thread
     */
    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }

    /**
     * Create the map associated with a ThreadLocal.
     *
     * @param t the current thread
     * @param firstValue value for the initial entry of the table.
     */
    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
    }
}
